import time
from copy import deepcopy
from functools import partial, reduce
from .const import *
from .behavior_trees import *


class BopType:
    Infantry, Vehicle, Aircraft = range(1, 4)


class BopSubTypes:
    """
    sub_type: 细分类型 坦克 0/  战车1 / 人员2 / 炮兵3 / 无人战车4 / 无人机5 / 直升机6 / 巡飞弹7 / 运输机8 / 侦察型战车9
    """
    Tank, Chariot, Infantry, Artillery, UCV, UAV, Helicopter, PM, TA, SC = list(range(0, 10))


def position_evaluate(see_enemy, tmp_bop, cur_map, mission_type=-1):
    # 只有无人战车和侦察型战车进行评估
    if (tmp_bop['sub_type'] != BopSubTypes.UCV and tmp_bop['sub_type'] != BopSubTypes.SC) or \
            len(see_enemy) == 0 or mission_type < 0:
        return None

    see_enemy_num = 0
    for enemy in see_enemy:
        if cur_map.check_2bop_see(tmp_bop, enemy):
            see_enemy_num += 1

    if mission_type == 0:
        flag = False
        be_seen_num = 0
        for enemy in see_enemy:
            distance = cur_map.get_distance(enemy['cur_hex'], tmp_bop['cur_hex'])
            if enemy['sub_type'] != BopSubTypes.Tank and distance <= 10:
                flag = True
            if cur_map.check_2bop_see(enemy, tmp_bop) and cur_map.get_distance(enemy['cur_hex'], tmp_bop['cur_hex']) <= 20:
                be_seen_num += 1
        if flag:
            if len(see_enemy) > 0 and be_seen_num // len(see_enemy) <= 0.2:
                return True
            else:
                return False
        else:
            return False

    elif mission_type == 1:
        be_seen_num = 0
        for enemy in see_enemy:
            if cur_map.check_2bop_see(enemy, tmp_bop) and cur_map.get_distance(enemy['cur_hex'], tmp_bop['cur_hex']) <= 20:
                be_seen_num += 1
        if len(see_enemy) > 0:
            if be_seen_num // len(see_enemy) <= 0.1:
                return True
            else:
                return False
        else:
            return True

    elif mission_type == 2:
        be_seen_num = 0
        for enemy in see_enemy:
            if cur_map.check_2bop_see(enemy, tmp_bop) and cur_map.get_distance(enemy['cur_hex'], tmp_bop['cur_hex'] <= 20):
                be_seen_num += 1
        if see_enemy_num > 0:
            if be_seen_num // see_enemy_num <= 0.5:
                return True
            else:
                return False
        else:
            return False

    else:
        return None


def target_pos_select(bop, see_enemy_bops, cur_map, mission_type=-1):
    # search_strategy
    start = 1
    target_pos = []
    tmp_bop = deepcopy(bop)
    see_enemy = [enemy for enemy in see_enemy_bops if (enemy['type'] != BopType.Aircraft)]

    def transfer_position(see_enemy, bop, ranges):
        # 从当前坐标的半径1开始找目标点，知道找到目标点或者半径大于20
        if mission_type < 0:
            return
        else:
            if ranges >= 20:
                return

        search_area = cur_map.get_grid_distance(bop['cur_hex'], ranges, ranges)
        search_tmp_bop = deepcopy(bop)
        for pos in search_area:
            if cur_map.is_in_soft(pos):
                continue
            search_tmp_bop['cur_hex'] = pos
            evaluate_result = position_evaluate(see_enemy, search_tmp_bop, cur_map, mission_type)
            if evaluate_result and pos != bop['cur_hex']:
                target_pos.append(pos)

        if not target_pos:
            transfer_position(see_enemy, bop, ranges + 1)

    if 0 <= mission_type <= 2:
        transfer_position(see_enemy, tmp_bop, start)

    if target_pos:
        print("my target_pos: ", target_pos)
        return target_pos
    else:
        return


def aircraft_recon_cities(bop, observation, cur_map, see_enemy_bops, mission_type=-1):
    ''' 侦察夺控点附近区域 '''
    if bop['type'] != BopType.Aircraft or mission_type < 0:
        return None

    if mission_type == 2:
        ct_scopeList = list(map(lambda ct: cur_map.get_grid_distance(ct["coord"], 0, 3) if ct["value"] == 50 else cur_map.get_grid_distance(ct["coord"], 0, 3), observation["cities"]))  # 目前暂定半径是3
        if ct_scopeList:
            need_recon_poss = reduce(lambda x, y: x | y, ct_scopeList)
            need_recon_poss = cur_map.get_grid_in_cover(need_recon_poss)
            if len(need_recon_poss):
                # 筛选出我方算子看不见的坐标
                # 包含了看见的敌方的算子
                need_recon_poss = {pos for pos in need_recon_poss if sum(map(lambda op: cur_map.can_see(op["cur_hex"], pos), observation["operators"])) == 0}
        else:
            need_recon_poss = None

        print("need_recon_poss: ", need_recon_poss)
        return list(need_recon_poss)

    elif mission_type == 0 or mission_type == 1:
        see_enemy = [enemy for enemy in see_enemy_bops if (enemy['type'] != BopType.Aircraft)]

        if bop['sub_type'] == BopSubTypes.PM and mission_type == 0:
            target = None
            target_pos = None

            if not target and len(see_enemy):
                min_blood = 100
                for enemy in see_enemy:
                    if enemy['blood'] < min_blood:
                        target = enemy
                        min_blood = enemy['blood']
            if not target:
                return None

            if target['cur_hex'] not in cur_map.get_PM_scope(bop["cur_hex"]):
                target_pos = target['cur_hex']
            return list(target_pos)

        else:
            need_recon_enemies = {enemy["cur_hex"] for enemy in see_enemy if enemy["sub_type"] in [0, 1, 2]}
            if observation["time"]["cur_step"] < 700:
                need_recon_enemies = need_recon_enemies - {infan['cur_hex'] for infan in see_enemy if infan["sub_type"] == BopSubTypes.Infantry}
            if not need_recon_enemies:
                return None

            print("need_recon_enemies: ", need_recon_enemies)
            return list(need_recon_enemies)
    else:
        return None


def diffuse_grids(gridList, cur_map, r1, r0=0):  # r1是大圆半径
    # 求出gridList的生成的圆区域的交
    gridList_d = map(lambda x: cur_map.get_grid_distance(x, r0, r1), gridList)
    # 集合的或与交一致
    return reduce(lambda x, y: x | y, gridList_d)


def gen_jm_pos(bop, see_enemy_bops, observation, cur_map):
    see_enemy = [enemy for enemy in see_enemy_bops if (enemy['type'] != BopType.Aircraft)]
    cities = [city["coord"] for city in observation['cities']]
    #  不是我方的步兵
    our_infan_poss = {op['cur_hex'] for op in observation['operators'] if op["sub_type"] == BopSubTypes.Infantry}
    target_pos = None
    infan_enemy = None
    if not infan_enemy:
        infan_enemy = [op for op in see_enemy if op["sub_type"] == BopSubTypes.Infantry]

    enemy_color = 1 if bop['color'] == 0 else 1

    if not target_pos and infan_enemy:
        for infan in infan_enemy:
            if infan["speed"] == 0 and infan["cur_hex"] not in our_infan_poss:
                target_pos = infan["cur_hex"]
                break

    # 位于主要夺控点的步兵算子
    main_cities = [city["coord"] for city in observation['cities'] if city["value"] == 80]
    cities_infan = [op for op in infan_enemy if op["cur_hex"] in main_cities]
    if not target_pos and len(cities_infan):
        for infan in cities_infan:
            if infan["move_path"][0] not in our_infan_poss:
                target_pos = infan["move_path"][0]
                break

    # 主要夺控点周围
    # 如果夺控点不是敌方的并且我方有人控夺，那么就瞄准对方算子
    # 如果夺控点不是敌方的但是没人控夺，就瞄准夺控点
    # 如果夺控点是敌方的，且敌方有人在控夺,则瞄准敌方算子
    our_poss = {op['cur_hex'] for op in observation['operators'] if op["type"] != BopType.Aircraft}
    cities_scope = diffuse_grids(main_cities, cur_map, 1, 1)
    cities_infan = [op for op in infan_enemy if op["cur_hex"] in cities_scope]
    if not target_pos and len(cities_infan):
        for infan in cities_infan:
            city_hex = min(main_cities, key=lambda x: cur_map.get_distance(infan["cur_hex"], x))
            city = [ct for ct in observation['cities'] if ct["coord"] == city_hex][0]
            city_scope = cur_map.get_grid_distance(city_hex, 0, 1)
            # 下面这句有问题
            if len(infan['move_path']):
                break

            if city["flag"] != enemy_color and len(city_scope & our_poss) and infan["move_path"][0] not in our_infan_poss:
                target_pos = infan["move_path"][0]
                break
            elif city["flag"] != enemy_color and not len(city_scope & our_poss) and city_hex not in our_poss:
                target_pos = city_hex
            elif city["flag"] == enemy_color and infan["move_path"][0] not in our_infan_poss:
                target_pos = infan["move_path"][0]
                break

    # 位于次要夺控点的步兵算子
    our_tank = {op["obj_id"] for op in observation['operators'] if op["sub_type"] == BopSubTypes.Tank}
    sub_cities = [city["coord"] for city in observation['cities'] if city["value"] == 50]
    cities_infan = [op for op in infan_enemy if len(op['move_path']) and op["move_path"][0] in sub_cities]
    if not target_pos and len(cities_infan) and len(our_tank):
        for infan in cities_infan:
            if infan["move_path"][0] not in our_infan_poss:
                target_pos = infan["move_path"][0]
                break

    return target_pos


def tank_gen_action(agent, cur_process_ids):
    agent.process_run_flag = False
    while True:
        # 通过的输入序列取出更新后的self
        a = time.time()
        agent.action_input_queue_locki[cur_process_ids].acquire()
        if agent.action_input_queuei[cur_process_ids].full():
            agent.process_run_flag = False  # 新的态势到达，行为树要继续运行,取消休眠状态
            agent.observation = agent.action_input_queuei[cur_process_ids].get()
            agent.situation.enemy = agent.action_input_queuei[cur_process_ids].get()
            agent.task = agent.action_input_queuei[cur_process_ids].get()
            agent.action_input_queue_locki[cur_process_ids].release()
        else:
            agent.action_input_queue_locki[cur_process_ids].release()
        if agent.process_run_flag:
            time.sleep(0.03)
            continue
        total_actions = []
        # 更新一些必要的信息
        a = time.time()
        # agent.controllable_ops = agent.observation["role_and_grouping_info"][agent.seat]["operators"]
        for obj_id, valid_actions in agent.observation["valid_actions"].items():
            bop = agent.get_bop(obj_id)
            if obj_id in cur_process_ids and obj_id in agent.task.keys():
                if agent.task[obj_id][0] == MissionType.Reconnaissance:
                    if agent.last_param[obj_id] != agent.task[obj_id][1]:
                        agent.bts[obj_id] = TankDetectTree(agent.task[obj_id][1])
                        agent.last_param[obj_id] = agent.task[obj_id][1]
                    if obj_id not in agent.bts.keys():
                        # 传入任务目标位置“target_pos”
                        agent.bts[obj_id] = TankDetectTree(agent.task[obj_id][1])
                        agent.last_param[obj_id] = agent.task[obj_id][1]
                    if not isinstance(agent.bts[bop['obj_id']], TankDetectTree):
                        agent.bts[bop['obj_id']] = TankDetectTree(agent.task[obj_id][1])
                        agent.last_param[obj_id] = agent.task[obj_id][1]
                    agent.bts[obj_id].update_bt(agent, obj_id)
                    if agent.task[obj_id] == MissionType.Defense and agent.bts[
                        obj_id].class_name == 'bttank_':  # todo:这什么玩意 ？？/？/？ 不是删过一次吗 怎么还在 23/7/5
                        agent.bts[obj_id] = TankDefenseTree()
                if agent.task[obj_id][0] == MissionType.Defense:
                    if agent.last_param[obj_id] != agent.task[obj_id][1]:
                        agent.bts[obj_id] = TankDefenseTree(agent.task[obj_id][1])
                        agent.last_param[obj_id] = agent.task[obj_id][1]
                    if obj_id not in agent.bts.keys():
                        agent.bts[obj_id] = TankDefenseTree(agent.task[obj_id][1])
                        agent.last_param[obj_id] = agent.task[obj_id][1]
                    if not isinstance(agent.bts[bop['obj_id']], TankDefenseTree):
                        agent.bts[bop['obj_id']] = TankDefenseTree(agent.task[obj_id][1])
                        agent.last_param[obj_id] = agent.task[obj_id][1]
                    agent.bts[obj_id].update_bt(agent, obj_id)
                if agent.task[obj_id][0] == MissionType.Attack:
                    if agent.last_param[obj_id] != agent.task[obj_id][1]:
                        agent.bts[obj_id] = TankAttackTree(agent.task[obj_id][1])
                        agent.last_param[obj_id] = agent.task[obj_id][1]
                    if obj_id not in agent.bts.keys():
                        agent.bts[obj_id] = TankAttackTree(agent.task[obj_id][1])
                        agent.last_param[obj_id] = agent.task[obj_id][1]
                    if not isinstance(agent.bts[bop['obj_id']], TankAttackTree):
                        agent.bts[bop['obj_id']] = TankAttackTree(agent.task[obj_id][1])
                        agent.last_param[obj_id] = agent.task[obj_id][1]
                    agent.bts[obj_id].update_bt(agent, obj_id)
                # debug
                if agent.bts[obj_id].actions:
                    print(f"==坦克行动: {agent.bts[obj_id].actions}")
                    total_actions += agent.bts[obj_id].actions

                    continue
                else:
                    continue
        b = time.time()
        agent.action_output_queue_locki[cur_process_ids].acquire()
        if agent.action_output_queuei[cur_process_ids].full():
            agent.action_output_queuei[cur_process_ids].get()
        if total_actions:  # 产生动作的时候输出往输出序列中放，否则输出序列是空的，在step中不需要获取没有产生动作的进程的锁
            agent.action_output_queuei[cur_process_ids].put(total_actions)
        agent.action_output_queue_locki[cur_process_ids].release()
        agent.process_run_flag = True
        if time.time()-a > 0.1:
            print("进程产生动作时间消耗1", time.time() - a, time.time()-b)
            print(total_actions)


def UGV_gen_action(agent, cur_process_ids):
    agent.process_run_flag = False
    while True:
        # 通过的输入序列取出更新后的self
        a = time.time()
        agent.action_input_queue_locki[cur_process_ids].acquire()
        if agent.action_input_queuei[cur_process_ids].full():
            agent.process_run_flag = False  # 新的态势到达，行为树要继续运行,取消休眠状态
            agent.observation = agent.action_input_queuei[cur_process_ids].get()
            agent.action_input_queuei[cur_process_ids].get()
            agent.task = agent.action_input_queuei[cur_process_ids].get()
            agent.action_input_queue_locki[cur_process_ids].release()
        else:
            agent.action_input_queue_locki[cur_process_ids].release()
        if agent.process_run_flag:
            time.sleep(0.03)
            continue
        total_actions = []
        # 更新一些必要的信息
        a = time.time()
        # agent.controllable_ops = agent.observation["role_and_grouping_info"][agent.seat]["operators"]
        for obj_id, valid_actions in agent.observation["valid_actions"].items():
            bop = agent.get_bop(obj_id)
            if obj_id in cur_process_ids and obj_id in agent.task.keys():
                if agent.last_param[obj_id] != agent.task[obj_id][1]:
                    agent.bts[obj_id] = UnmannedVehiclesDefendTree(agent.task[obj_id][1])
                    agent.last_param[obj_id] = agent.task[obj_id][1]
                if obj_id not in agent.bts.keys():
                    # 传入任务目标位置“target_pos”，如果target_pos=None，表示防守目标是夺控点
                    agent.bts[obj_id] = UnmannedVehiclesDefendTree(agent.task[obj_id][1])
                    agent.last_param[obj_id] = agent.task[obj_id][1]
                if not isinstance(agent.bts[bop['obj_id']], UnmannedVehiclesDefendTree):
                    agent.bts[obj_id] = UnmannedVehiclesDefendTree(agent.task[obj_id][1])
                    agent.last_param[obj_id] = agent.task[obj_id][1]
                agent.bts[obj_id].update_bt(agent, obj_id)
                # debug
                if agent.bts[obj_id].actions:
                    print(f"===无人战车行动: {agent.bts[obj_id].actions}")
                    total_actions += agent.bts[obj_id].actions
                    continue  # 进入此代码段后，不再执行下面的代码
                else:
                    continue
        b = time.time()
        agent.action_output_queue_locki[cur_process_ids].acquire()
        if agent.action_output_queuei[cur_process_ids].full():
            agent.action_output_queuei[cur_process_ids].get()
        if total_actions:  # 产生动作的时候输出往输出序列中放，否则输出序列是空的，在step中不需要获取没有产生动作的进程的锁
            agent.action_output_queuei[cur_process_ids].put(total_actions)
        agent.action_output_queue_locki[cur_process_ids].release()
        agent.process_run_flag = True
        if time.time()-a > 0.1:
            print("进程产生动作时间消耗2", time.time() - a, time.time()-b)
            print(total_actions)


def Infantry_gen_action(agent, cur_process_ids):
    agent.process_run_flag = False
    while True:
        # 通过的输入序列取出更新后的self
        a = time.time()
        agent.action_input_queue_locki[cur_process_ids].acquire()
        if agent.action_input_queuei[cur_process_ids].full():
            agent.process_run_flag = False  # 新的态势到达，行为树要继续运行,取消休眠状态
            agent.observation = agent.action_input_queuei[cur_process_ids].get()
            agent.action_input_queuei[cur_process_ids].get()
            agent.task = agent.action_input_queuei[cur_process_ids].get()
            agent.action_input_queue_locki[cur_process_ids].release()
        else:
            agent.action_input_queue_locki[cur_process_ids].release()
        if agent.process_run_flag:
            time.sleep(0.03)
            continue
        total_actions = []
        # 更新一些必要的信息
        # agent.controllable_ops = agent.observation["role_and_grouping_info"][agent.seat]["operators"]
        a = time.time()
        for obj_id, valid_actions in agent.observation["valid_actions"].items():
            bop = agent.get_bop(obj_id)
            if obj_id in cur_process_ids and obj_id in agent.task.keys():
                if bop['sub_type'] == BopSubType.Infantry:
                    if agent.task[obj_id][0] == MissionType.Defense:
                        if obj_id not in agent.bts.keys():
                            agent.bts[bop['obj_id']] = infantry_defence_tree()
                        if not isinstance(agent.bts[bop['obj_id']], infantry_defence_tree):
                            agent.bts[bop['obj_id']] = infantry_defence_tree()
                        agent.bts[obj_id].update_bt(agent, obj_id)
                    elif agent.task[obj_id][0] == MissionType.Reconnaissance:
                        if obj_id not in agent.bts.keys():
                            agent.bts[obj_id] = infantry_defence_tree()
                        if not isinstance(agent.bts[bop['obj_id']], infantry_defence_tree):
                            agent.bts[obj_id] = infantry_defence_tree()
                        agent.bts[obj_id].update_bt(agent, i)
                    elif agent.task[obj_id][0] == MissionType.Attack:
                        # 如果步兵所属战车已经阵亡 则步兵转为防御任务 开始向夺控点前进
                        if agent.get_bop(bop['launcher']):
                            if obj_id not in agent.bts.keys():
                                agent.bts[bop['obj_id']] = infantry_attack_tree()
                            if not isinstance(agent.bts[bop['obj_id']], infantry_attack_tree):
                                agent.bts[bop['obj_id']] = infantry_attack_tree()
                        else:
                            if obj_id not in agent.bts.keys():
                                agent.bts[bop['obj_id']] = infantry_defence_tree()
                            if not isinstance(agent.bts[bop['obj_id']], infantry_defence_tree):
                                agent.bts[bop['obj_id']] = infantry_defence_tree()
                        agent.bts[obj_id].update_bt(agent, obj_id)
                    # debug
                    if agent.bts[obj_id].actions:
                        # print(f"===步兵行动: {agent.bts[obj_id].actions}")
                        total_actions += agent.bts[obj_id].actions
                        continue
                    else:
                        continue
                elif bop['sub_type'] == BopSubType.IFV:  # 执行战车的防御任务
                    if bop['passenger_ids']:
                        for i in bop['passenger_ids']:
                            passenger_of_bop = agent.get_bop(i)
                            if passenger_of_bop['sub_type'] == BopSubType.Infantry:
                                # print(f'步兵正在执行的任务：{self.task[i][0]}')
                                if agent.task[i][0] == MissionType.Defense:
                                    if i not in agent.bts.keys():
                                        agent.bts[i] = infantry_defence_tree()
                                    if not isinstance(agent.bts[passenger_of_bop['obj_id']], infantry_defence_tree):
                                        agent.bts[i] = infantry_defence_tree()
                                    agent.bts[i].update_bt(agent, i)
                                elif agent.task[i][0] == MissionType.Attack:
                                    if i not in agent.bts.keys():
                                        agent.bts[i] = infantry_attack_tree()
                                    if not isinstance(agent.bts[passenger_of_bop['obj_id']], infantry_attack_tree):
                                        agent.bts[i] = infantry_attack_tree()
                                    agent.bts[i].update_bt(agent, i)
                                elif agent.task[i][0] == MissionType.Reconnaissance:
                                    if i not in agent.bts.keys():
                                        agent.bts[i] = infantry_defence_tree()
                                    if not isinstance(agent.bts[passenger_of_bop['obj_id']], infantry_defence_tree):
                                        agent.bts[i] = infantry_defence_tree()
                                    agent.bts[i].update_bt(agent, i)
                                # debug
                                if agent.bts[i].actions:
                                    print(f"===步兵行动: {agent.bts[i].actions}")
                                    total_actions += agent.bts[i].actions
                    if agent.task[obj_id][0] == MissionType.Reconnaissance:
                        if agent.last_param[obj_id] != agent.task[obj_id][1]:
                            agent.bts[obj_id] = IFVDetectTree(agent.task[obj_id][1])
                            agent.last_param[obj_id] = agent.task[obj_id][1]
                        if obj_id not in agent.bts.keys():
                            # 传入任务目标位置“target_pos”
                            agent.bts[obj_id] = IFVDetectTree(agent.task[obj_id][1])
                            agent.last_param[obj_id] = agent.task[obj_id][1]
                        if not isinstance(agent.bts[bop['obj_id']], IFVDetectTree):
                            agent.bts[bop['obj_id']] = IFVDetectTree(agent.task[obj_id][1])
                            agent.last_param[obj_id] = agent.task[obj_id][1]
                        agent.bts[obj_id].update_bt(agent, obj_id)
                        # debug
                    elif agent.task[obj_id][0] == MissionType.Defense:
                        if agent.last_param[obj_id] != agent.task[obj_id][1]:
                            agent.bts[obj_id] = IFVDefenseTree(agent.task[obj_id][1])
                            agent.last_param[obj_id] = agent.task[obj_id][1]
                        if obj_id not in agent.bts.keys():
                            # 传入任务目标位置“target_pos”
                            agent.bts[obj_id] = IFVDefenseTree(agent.task[obj_id][1])
                            agent.last_param[obj_id] = agent.task[obj_id][1]
                        if not isinstance(agent.bts[bop['obj_id']], IFVDefenseTree):
                            agent.bts[bop['obj_id']] = IFVDefenseTree(agent.task[obj_id][1])
                            agent.last_param[obj_id] = agent.task[obj_id][1]
                        agent.bts[obj_id].update_bt(agent, obj_id)
                        # debug
                    elif agent.task[obj_id][0] == MissionType.Attack:
                        if agent.last_param[obj_id] != agent.task[obj_id][1]:
                            agent.bts[obj_id] = IFVAttackTree(agent.task[obj_id][1])
                            agent.last_param[obj_id] = agent.task[obj_id][1]
                        if obj_id not in agent.bts.keys():
                            # 传入任务目标位置“target_pos”
                            agent.bts[obj_id] = IFVAttackTree(agent.task[obj_id][1])
                            agent.last_param[obj_id] = agent.task[obj_id][1]
                        if not isinstance(agent.bts[bop['obj_id']], IFVAttackTree):
                            agent.bts[bop['obj_id']] = IFVAttackTree(agent.task[obj_id][1])
                            agent.last_param[obj_id] = agent.task[obj_id][1]
                        agent.bts[obj_id].update_bt(agent, obj_id)
                        # debug
                    if agent.bts[obj_id].actions:
                        print(f"==战车行动: {agent.bts[obj_id].actions}")
                        total_actions += agent.bts[obj_id].actions
                        continue
                    else:
                        continue
        b = time.time()
        agent.action_output_queue_locki[cur_process_ids].acquire()
        if agent.action_output_queuei[cur_process_ids].full():
            agent.action_output_queuei[cur_process_ids].get()
        if total_actions:  # 产生动作的时候输出往输出序列中放，否则输出序列是空的，在step中不需要获取没有产生动作的进程的锁
            agent.action_output_queuei[cur_process_ids].put(total_actions)
        agent.action_output_queue_locki[cur_process_ids].release()
        agent.process_run_flag = True
        if time.time()-a > 0.1:
            print("进程产生动作时间消耗3", time.time() - a, time.time()-b)
            print(total_actions)


def gen_task_process(agent):
    agent.run_flag = False  # 当前态势计算结束后没有新的态势到来，释放资源
    while True:
        # 通过agent中的输入序列取出态势
        agent.task_input_queue_lock.acquire()
        if agent.task_input_queue.full():
            agent.run_flag = False
            agent.situation.enemy = agent.task_input_queue.get()
            agent.observation = agent.task_input_queue.get()
            agent.task_input_queue_lock.release()
        else:
            agent.task_input_queue_lock.release()
        if agent.run_flag:
            time.sleep(0.02)
            continue
        ## 意图层：事件触发的判断 产生新的mission
        agent.whole_mission_schedule.update(agent)
        # print('意图层结束')
        # 如果态势发生改变
        if agent.whole_mission_schedule.mission_flag:
            print('-----------------------------------')
            print('态势发生变化')
            # ## 兵力筹划层：对算子进行分队和意图推理
            # self.squad = self.whole_task_allocation.step(self,self.whole_task_allocation.mission)
            # ## 任务分配层：对每个分队进行任务分配 最后放到一个list中交给算子行为层执行
            # for i in self.squad:
            #     self.task += self.task_allocation.step(self, self.squad)
            ## 兵力筹划层+任务分配层：对算子进行分队和意图推理和分配任务
            tasks = agent.whole_task_allocation.step(agent, agent.whole_task_allocation.mission)
            for i in tasks:
                for j in i['member']:
                    operator_task_dict = {j[0]: [j[1], i['city']]}
                    agent.task.update(operator_task_dict)
            print('任务分配结束')

            # 输出数据的位置
            agent.task_output_queue_lock.acquire()
            if agent.task_output_queue.full():
                agent.task_output_queue.get()
            agent.task_output_queue.put(agent.task)
            agent.task_output_queue_lock.release()
        agent.run_flag = True